package pl.wr.aspect.performance.util;

/**
 * @author wieslaw.rodak
 * 
 */
public class InvokeStatistics implements Comparable<InvokeStatistics> {

	private final String methodName;
	private long invokeCount = 0;
	private long totalTime = 0;
	private long minTime = Long.MAX_VALUE;
	private long maxTime = Long.MIN_VALUE;

	public InvokeStatistics(final String method) {
		this.methodName = method;
	}

	public void addTime(final long time) {
		totalTime += time;
		minTime = Math.min(minTime, time);
		maxTime = Math.max(maxTime, time);
		invokeCount++;
	}

	@Override
	public int compareTo(InvokeStatistics o) {
		return (totalTime < o.totalTime ? -1 : (totalTime == o.totalTime ? 0 : 1));
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (int) (invokeCount ^ (invokeCount >>> 32));
		result = prime * result + (int) (maxTime ^ (maxTime >>> 32));
		result = prime * result + ((methodName == null) ? 0 : methodName.hashCode());
		result = prime * result + (int) (minTime ^ (minTime >>> 32));
		result = prime * result + (int) (totalTime ^ (totalTime >>> 32));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		InvokeStatistics other = (InvokeStatistics) obj;
		if (invokeCount != other.invokeCount)
			return false;
		if (maxTime != other.maxTime)
			return false;
		if (methodName == null) {
			if (other.methodName != null)
				return false;
		} else if (!methodName.equals(other.methodName))
			return false;
		if (minTime != other.minTime)
			return false;
		if (totalTime != other.totalTime)
			return false;
		return true;
	}

	/**
	 * @return The method name.
	 */
	public String getMethodName() {
		return methodName;
	}

	/**
	 * @return The invoke count.
	 */
	public long getInvokeCount() {
		return invokeCount;
	}

	/**
	 * @return The total executed time.
	 */
	public long getTotalTime() {
		return totalTime;
	}

	/**
	 * @return The minimum executed time.
	 */
	public long getMinTime() {
		return minTime;
	}

	/**
	 * @return The maximum executed time.
	 */
	public long getMaxTime() {
		return maxTime;
	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("InvokeStatistics [methodName=");
		builder.append(methodName);
		builder.append(", invokeCount=");
		builder.append(invokeCount);
		builder.append(", totalTime=");
		builder.append(totalTime);
		builder.append("ms");
		builder.append(", minTime=");
		builder.append(minTime);
		builder.append("ms");
		builder.append(", maxTime=");
		builder.append(maxTime);
		builder.append("ms");
		builder.append("]");
		return builder.toString();
	}

}
